﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using VueShopApi.Dtos;

namespace VueShopApi.Common
{
    [Authorize]
    [ApiExplorerSettings(GroupName = "v1")]
    public class AuthorizeController : ControllerBase
    {
        protected List<PermissionDto> GetRoleMenus(List<PermissionApiIncludePermissionDto> permissions, int roleId, List<int> rolePermissionIds)
        {
            var permissionsResult = new Dictionary<int, PermissionDto>();
            var permissionKeys = permissions.ToDictionary(p => p.PsId, p => p);

            foreach (var permission in permissions.Where(p => p.PsLevel == 0))
            {
                // 处理一级菜单
                if (roleId != 0)
                {
                    if (!rolePermissionIds.Contains(permission.PsId)) continue; ;
                }

                permissionsResult.Add(permission.PsId, new PermissionDto
                {
                    Id = permission.PsId,
                    AuthName = permission.PsName,
                    Path = permission.PsApiPath,
                    Children = new List<PermissionDto>(),
                    Order = permission.PsApiOrder
                });
            }

            foreach (var permission in permissions.Where(p => p.PsLevel == 1))
            {
                // 处理二级菜单
                if (roleId != 0)
                {
                    if (!rolePermissionIds.Contains(permission.PsId)) continue; ;
                }

                if (permissionsResult.TryGetValue(permission.PsPid, out var parentKeyPermission))
                {
                    parentKeyPermission.Children.Add(new PermissionDto
                    {
                        Id = permission.PsId,
                        AuthName = permission.PsName,
                        Path = permission.PsApiPath,
                        Children = new List<PermissionDto>(),
                        Order = permission.PsApiOrder
                    });
                }
            }

            // 排序
            var result = permissionsResult.Values.ToList();
            result = result.OrderBy(p => p.Order).ToList();
            foreach (var item in result)
            {
                item.Children = item.Children.OrderBy(c => c.Order).ToList();
            }

            return result;
        }

        protected List<PermissionDto> GetPermissionsResult(Dictionary<int, PermissionApiIncludePermissionDto> permissionKeys, List<int> permissionIds, int level = 3)
        {
            var permissionsResult = new Dictionary<int, PermissionDto>();
            var secondPermissionsResult = new Dictionary<int, PermissionDto>();

            if (level <= 0)
                return permissionsResult.Values.ToList();

            foreach (var permissionId in permissionIds)
            {
                //  处理一级菜单
                if (permissionKeys.TryGetValue(permissionId, out PermissionApiIncludePermissionDto permission))
                {
                    if (permission != null && permission.PsLevel == 0)
                    {
                        permissionsResult.Add(permission.PsId, new PermissionDto
                        {
                            Id = permission.PsId,
                            AuthName = permission.PsName,
                            Path = permission.PsApiPath,
                            Children = new List<PermissionDto>(),
                            Order = permission.PsApiOrder
                        });
                    }
                }
            }

            if (level == 1)
                return permissionsResult.Values.ToList();

            foreach (var permissionId in permissionIds)
            {
                //  处理二级菜单
                if (permissionKeys.TryGetValue(permissionId, out PermissionApiIncludePermissionDto permission))
                {
                    if (permission != null && permission.PsLevel == 1)
                    {
                        if (permissionsResult.TryGetValue(permission.PsPid, out var parentPermissionResult))
                        {
                            secondPermissionsResult.Add(permission.PsId, new PermissionDto
                            {
                                Id = permission.PsId,
                                AuthName = permission.PsName,
                                Path = permission.PsApiPath,
                                Children = new List<PermissionDto>(),
                                Order = permission.PsApiOrder
                            });
                            parentPermissionResult.Children.Add(secondPermissionsResult[permission.PsId]);
                        }
                    }
                }
            }

            if (level == 2)
                return permissionsResult.Values.ToList();

            foreach (var permissionId in permissionIds)
            {
                //  处理三级菜单
                if (permissionKeys.TryGetValue(permissionId, out PermissionApiIncludePermissionDto permission))
                {
                    if (permission != null && permission.PsLevel == 2)
                    {
                        if (secondPermissionsResult.TryGetValue(permission.PsPid, out var parentPermissionResult))
                        {
                            parentPermissionResult.Children.Add(new PermissionDto
                            {
                                Id = permission.PsId,
                                AuthName = permission.PsName,
                                Path = permission.PsApiPath,
                                Order = permission.PsApiOrder
                            });
                        }
                    }
                }
            }

            if (level >= 3)
                return permissionsResult.Values.ToList();

            return permissionsResult.Values.ToList();
        }

        protected List<PermissionTreeDto> GetPermissionsTree(List<PermissionApiIncludePermissionDto> permissions, int level = 3)
        {
            var permissionKeys = permissions.ToDictionary(p => p.PsId, p => p);

            var permissionsResult = new Dictionary<int, PermissionTreeDto>();
            var secondPermissionsResult = new Dictionary<int, PermissionTreeDto>();

            if (level <= 0)
                return permissionsResult.Values.ToList();

            foreach (var permission in permissions.Where(p => p.PsLevel == 0))
            {
                //  处理一级菜单
                permissionsResult.Add(permission.PsId, new PermissionTreeDto
                {
                    Id = permission.PsId,
                    AuthName = permission.PsName,
                    Path = permission.PsApiPath,
                    Pid = permission.PsPid + "",
                    Children = new List<PermissionTreeDto>(),
                });
            }

            if (level == 1)
                return permissionsResult.Values.ToList();

            foreach (var permission in permissions.Where(p => p.PsLevel == 1))
            {
                //  处理二级菜单
                if (permissionsResult.TryGetValue(permission.PsPid, out var parentPermissionResult))
                {
                    secondPermissionsResult.Add(permission.PsId, new PermissionTreeDto
                    {
                        Id = permission.PsId,
                        AuthName = permission.PsName,
                        Path = permission.PsApiPath,
                        Pid = permission.PsPid + "",
                        Children = new List<PermissionTreeDto>(),
                    });
                    parentPermissionResult.Children.Add(secondPermissionsResult[permission.PsId]);
                }
            }

            if (level == 2)
                return permissionsResult.Values.ToList();

            foreach (var permission in permissions.Where(p => p.PsLevel == 2))
            {
                //  处理三级菜单
                if (secondPermissionsResult.TryGetValue(permission.PsPid, out var parentPermissionResult))
                {
                    parentPermissionResult.Children.Add(new PermissionTreeDto
                    {
                        Id = permission.PsId,
                        AuthName = permission.PsName,
                        Path = permission.PsApiPath,
                        Pid = permission.PsPid + "," + permissionKeys[permission.PsPid].PsPid,
                        Children = new List<PermissionTreeDto>(),
                    });
                }
            }

            if (level >= 3)
                return permissionsResult.Values.ToList();

            return permissionsResult.Values.ToList();
        }

        protected List<CategoryDto> GetCategoriesTree(List<CategoryDto> categories, int type)
        {
            var result = new List<CategoryDto>();

            var categoryKeys = categories.ToDictionary(c => c.CatId, c => c);

            static bool IsCategoryDeleted(Dictionary<int, CategoryDto> categoryKeys, CategoryDto category)
            {
                if (category.CatPid == 0)
                {
                    return category.CatDeleted;
                }
                else if (category.CatDeleted)
                {
                    return true;
                }
                else
                {
                    categoryKeys.TryGetValue(category.CatPid, out var parentCategory);
                    if (parentCategory == null) return true;
                    return IsCategoryDeleted(categoryKeys, parentCategory);
                }
            }

            foreach (var category in categories)
            {
                // 判断是否被删除
                if (IsCategoryDeleted(categoryKeys, category)) continue;
                if (category.CatPid == 0)
                {
                    result.Add(category);
                }
                else
                {
                    if (category.CatLevel >= type) continue;

                    categoryKeys.TryGetValue(category.CatPid, out var parentCategory);
                    if (parentCategory == null) continue;
                    if (parentCategory.Children == null)
                    {
                        parentCategory.Children = new List<CategoryDto>();
                    }
                    parentCategory.Children.Add(category);
                }
            }

            return result;
        }
    }
}
